<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>8 dplyr | Tidy evaluation</title>
  <meta name="description" content="这本书的目的是让你跟上 tidy evaluation 的进度，以及如何围绕 tidyverse 流程和语法编写函数" />
  <meta name="generator" content="bookdown 0.11 and GitBook 2.6.7" />

  <meta property="og:title" content="8 dplyr | Tidy evaluation" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="这本书的目的是让你跟上 tidy evaluation 的进度，以及如何围绕 tidyverse 流程和语法编写函数" />
  <meta name="github-repo" content="ShixiangWang/tidyeval-chinese" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="8 dplyr | Tidy evaluation" />
  
  <meta name="twitter:description" content="这本书的目的是让你跟上 tidy evaluation 的进度，以及如何围绕 tidyverse 流程和语法编写函数" />
  

<meta name="author" content="Lionel Henry" />
<meta name="author" content="Hadley Wickham" />
<meta name="author" content="王诗翔（译）" />



  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="glossary.html">
<link rel="next" href="ggplot2.html">
<script src="libs/jquery-2.2.3/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />







<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-115082821-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-115082821-1');
</script>


<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(data-line-number);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="adv-r.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><strong><a href="./">Tidy evaluation</a></strong></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>欢迎</a><ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#e585b6e4bb96e8b584e6ba90"><i class="fa fa-check"></i>其他资源</a></li>
</ul></li>
<li class="part"><span><b>I 原理</b></span></li>
<li class="chapter" data-level="1" data-path="section-1.html"><a href="section-1.html"><i class="fa fa-check"></i><b>1</b> 介绍</a></li>
<li class="chapter" data-level="2" data-path="sec-why-how.html"><a href="sec-why-how.html"><i class="fa fa-check"></i><b>2</b> 为什么使用以及怎么使用</a><ul>
<li class="chapter" data-level="2.1" data-path="sec-why-how.html"><a href="sec-why-how.html#section-2.1"><i class="fa fa-check"></i><b>2.1</b> 数据隐藏</a></li>
<li class="chapter" data-level="2.2" data-path="sec-why-how.html"><a href="sec-why-how.html#section-2.2"><i class="fa fa-check"></i><b>2.2</b> 引用代码</a></li>
<li class="chapter" data-level="2.3" data-path="sec-why-how.html"><a href="sec-why-how.html#section-2.3"><i class="fa fa-check"></i><b>2.3</b> 去引用代码</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="sec-do-you-need.html"><a href="sec-do-you-need.html"><i class="fa fa-check"></i><b>3</b> 你需要 tidy eval 吗？</a><ul>
<li class="chapter" data-level="3.1" data-path="sec-do-you-need.html"><a href="sec-do-you-need.html#sec:fixed-colnames"><i class="fa fa-check"></i><b>3.1</b> 固定列名</a></li>
<li class="chapter" data-level="3.2" data-path="sec-do-you-need.html"><a href="sec-do-you-need.html#sec:automating-loops"><i class="fa fa-check"></i><b>3.2</b> 自动循环</a><ul>
<li class="chapter" data-level="3.2.1" data-path="sec-do-you-need.html"><a href="sec-do-you-need.html#dplyr-"><i class="fa fa-check"></i><b>3.2.1</b> dplyr 中的向量化</a></li>
<li class="chapter" data-level="3.2.2" data-path="sec-do-you-need.html"><a href="sec-do-you-need.html#section-3.2.2"><i class="fa fa-check"></i><b>3.2.2</b> 按列循环</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="4" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html"><i class="fa fa-check"></i><b>4</b> 加速</a><ul>
<li class="chapter" data-level="4.1" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.1"><i class="fa fa-check"></i><b>4.1</b> 编写函数</a><ul>
<li class="chapter" data-level="4.1.1" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.1.1"><i class="fa fa-check"></i><b>4.1.1</b> 减少重复</a></li>
<li class="chapter" data-level="4.1.2" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.1.2"><i class="fa fa-check"></i><b>4.1.2</b> 引用函数的特殊之处在哪？</a></li>
<li class="chapter" data-level="4.1.3" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.1.3"><i class="fa fa-check"></i><b>4.1.3</b> 去引用</a></li>
<li class="chapter" data-level="4.1.4" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#-qq_show-"><i class="fa fa-check"></i><b>4.1.4</b> 通过 <code>qq_show()</code> 理解 <code>!!</code></a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.2"><i class="fa fa-check"></i><b>4.2</b> 引用和去引用</a><ul>
<li class="chapter" data-level="4.2.1" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.2.1"><i class="fa fa-check"></i><b>4.2.1</b> 第一步：抽取</a></li>
<li class="chapter" data-level="4.2.2" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.2.2"><i class="fa fa-check"></i><b>4.2.2</b> 第二步：引用</a></li>
<li class="chapter" data-level="4.2.3" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.2.3"><i class="fa fa-check"></i><b>4.2.3</b> 第三步：去引用</a></li>
<li class="chapter" data-level="4.2.4" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.2.4"><i class="fa fa-check"></i><b>4.2.4</b> 结果</a></li>
</ul></li>
<li class="chapter" data-level="4.3" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.3"><i class="fa fa-check"></i><b>4.3</b> 用字符串取代引用</a><ul>
<li class="chapter" data-level="4.3.1" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.3.1"><i class="fa fa-check"></i><b>4.3.1</b> 字符串</a></li>
<li class="chapter" data-level="4.3.2" data-path="sec-up-to-speed.html"><a href="sec-up-to-speed.html#section-4.3.2"><i class="fa fa-check"></i><b>4.3.2</b> 包含列名的字符串向量</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="5" data-path="multiple.html"><a href="multiple.html"><i class="fa fa-check"></i><b>5</b> Dealing with multiple arguments</a><ul>
<li class="chapter" data-level="5.1" data-path="multiple.html"><a href="multiple.html#the-...-argument"><i class="fa fa-check"></i><b>5.1</b> The <code>...</code> argument</a></li>
<li class="chapter" data-level="5.2" data-path="multiple.html"><a href="multiple.html#simple-forwarding-of-..."><i class="fa fa-check"></i><b>5.2</b> Simple forwarding of <code>...</code></a></li>
<li class="chapter" data-level="5.3" data-path="multiple.html"><a href="multiple.html#quote-multiple-arguments"><i class="fa fa-check"></i><b>5.3</b> Quote multiple arguments</a></li>
<li class="chapter" data-level="5.4" data-path="multiple.html"><a href="multiple.html#unquote-multiple-arguments"><i class="fa fa-check"></i><b>5.4</b> Unquote multiple arguments</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="modifying-inputs.html"><a href="modifying-inputs.html"><i class="fa fa-check"></i><b>6</b> Modifying inputs</a><ul>
<li class="chapter" data-level="6.1" data-path="modifying-inputs.html"><a href="modifying-inputs.html#modifying-names"><i class="fa fa-check"></i><b>6.1</b> Modifying names</a><ul>
<li class="chapter" data-level="6.1.1" data-path="modifying-inputs.html"><a href="modifying-inputs.html#default-argument-names"><i class="fa fa-check"></i><b>6.1.1</b> Default argument names</a></li>
<li class="chapter" data-level="6.1.2" data-path="modifying-inputs.html"><a href="modifying-inputs.html#unquoting-argument-names"><i class="fa fa-check"></i><b>6.1.2</b> Unquoting argument names</a></li>
<li class="chapter" data-level="6.1.3" data-path="modifying-inputs.html"><a href="modifying-inputs.html#prefixing-quoted-arguments"><i class="fa fa-check"></i><b>6.1.3</b> Prefixing quoted arguments</a></li>
</ul></li>
<li class="chapter" data-level="6.2" data-path="modifying-inputs.html"><a href="modifying-inputs.html#modifying-quoted-expressions"><i class="fa fa-check"></i><b>6.2</b> Modifying quoted expressions</a><ul>
<li class="chapter" data-level="6.2.1" data-path="modifying-inputs.html"><a href="modifying-inputs.html#expanding-quoted-expressions-with-expr"><i class="fa fa-check"></i><b>6.2.1</b> Expanding quoted expressions with <code>expr()</code></a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="7" data-path="glossary.html"><a href="glossary.html"><i class="fa fa-check"></i><b>7</b> Glossary</a><ul>
<li class="chapter" data-level="7.1" data-path="glossary.html"><a href="glossary.html#data-structures"><i class="fa fa-check"></i><b>7.1</b> Data structures</a><ul>
<li class="chapter" data-level="7.1.1" data-path="glossary.html"><a href="glossary.html#glossary-data-mask"><i class="fa fa-check"></i><b>7.1.1</b> TODO Data mask</a></li>
<li class="chapter" data-level="7.1.2" data-path="glossary.html"><a href="glossary.html#glossary-expr"><i class="fa fa-check"></i><b>7.1.2</b> Expression</a></li>
<li class="chapter" data-level="7.1.3" data-path="glossary.html"><a href="glossary.html#expression-base"><i class="fa fa-check"></i><b>7.1.3</b> Expression (base)</a></li>
<li class="chapter" data-level="7.1.4" data-path="glossary.html"><a href="glossary.html#glossary-sym"><i class="fa fa-check"></i><b>7.1.4</b> TODO Symbol</a></li>
</ul></li>
<li class="chapter" data-level="7.2" data-path="glossary.html"><a href="glossary.html#programming-concepts"><i class="fa fa-check"></i><b>7.2</b> Programming Concepts</a><ul>
<li class="chapter" data-level="7.2.1" data-path="glossary.html"><a href="glossary.html#glossary-constant-symbolic"><i class="fa fa-check"></i><b>7.2.1</b> Constant versus symbolic</a></li>
<li class="chapter" data-level="7.2.2" data-path="glossary.html"><a href="glossary.html#glossary-nse"><i class="fa fa-check"></i><b>7.2.2</b> TODO Non-Standard Evaluation (NSE)</a></li>
<li class="chapter" data-level="7.2.3" data-path="glossary.html"><a href="glossary.html#glossary-quotation-evaluation"><i class="fa fa-check"></i><b>7.2.3</b> TODO Quotation versus Evaluation</a></li>
<li class="chapter" data-level="7.2.4" data-path="glossary.html"><a href="glossary.html#glossary-qq"><i class="fa fa-check"></i><b>7.2.4</b> TODO Quasiquotation</a></li>
<li class="chapter" data-level="7.2.5" data-path="glossary.html"><a href="glossary.html#glossary-parse"><i class="fa fa-check"></i><b>7.2.5</b> TODO Parsing</a></li>
<li class="chapter" data-level="7.2.6" data-path="glossary.html"><a href="glossary.html#glossary-metaprogramming"><i class="fa fa-check"></i><b>7.2.6</b> TODO Metaprogramming</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Cookbooks</b></span></li>
<li class="chapter" data-level="8" data-path="dplyr.html"><a href="dplyr.html"><i class="fa fa-check"></i><b>8</b> dplyr</a><ul>
<li class="chapter" data-level="8.1" data-path="dplyr.html"><a href="dplyr.html#patterns-for-single-arguments"><i class="fa fa-check"></i><b>8.1</b> Patterns for single arguments</a><ul>
<li class="chapter" data-level="8.1.1" data-path="dplyr.html"><a href="dplyr.html#enquo-and---quote-and-unquote-arguments"><i class="fa fa-check"></i><b>8.1.1</b> <code>enquo()</code> and <code>!!</code> - Quote and unquote arguments</a></li>
<li class="chapter" data-level="8.1.2" data-path="dplyr.html"><a href="dplyr.html#quo_name---create-default-column-names"><i class="fa fa-check"></i><b>8.1.2</b> <code>quo_name()</code> - Create default column names</a></li>
<li class="chapter" data-level="8.1.3" data-path="dplyr.html"><a href="dplyr.html#and---unquote-column-names"><i class="fa fa-check"></i><b>8.1.3</b> <code>:=</code> and <code>!!</code> - Unquote column names</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="dplyr.html"><a href="dplyr.html#patterns-for-multiple-arguments"><i class="fa fa-check"></i><b>8.2</b> Patterns for multiple arguments</a><ul>
<li class="chapter" data-level="8.2.1" data-path="dplyr.html"><a href="dplyr.html#forward-multiple-arguments"><i class="fa fa-check"></i><b>8.2.1</b> <code>...</code> - Forward multiple arguments</a></li>
<li class="chapter" data-level="8.2.2" data-path="dplyr.html"><a href="dplyr.html#enquos-and---quote-and-unquote-multiple-arguments"><i class="fa fa-check"></i><b>8.2.2</b> <code>enquos()</code> and <code>!!!</code> - Quote and unquote multiple arguments</a></li>
<li class="chapter" data-level="8.2.3" data-path="dplyr.html"><a href="dplyr.html#expr---modify-quoted-arguments"><i class="fa fa-check"></i><b>8.2.3</b> <code>expr()</code> - Modify quoted arguments</a></li>
<li class="chapter" data-level="8.2.4" data-path="dplyr.html"><a href="dplyr.html#sec:external-quoting"><i class="fa fa-check"></i><b>8.2.4</b> <code>vars()</code> - Quote multiple arguments externally</a></li>
<li class="chapter" data-level="8.2.5" data-path="dplyr.html"><a href="dplyr.html#enquos.named-true---automatically-add-default-names"><i class="fa fa-check"></i><b>8.2.5</b> <code>enquos(.named = TRUE)</code> - Automatically add default names</a></li>
<li class="chapter" data-level="8.2.6" data-path="dplyr.html"><a href="dplyr.html#quos_auto_name---manually-add-default-names"><i class="fa fa-check"></i><b>8.2.6</b> <code>quos_auto_name()</code> - Manually add default names</a></li>
</ul></li>
<li class="chapter" data-level="8.3" data-path="dplyr.html"><a href="dplyr.html#select"><i class="fa fa-check"></i><b>8.3</b> <code>select()</code></a></li>
<li class="chapter" data-level="8.4" data-path="dplyr.html"><a href="dplyr.html#filter"><i class="fa fa-check"></i><b>8.4</b> <code>filter()</code></a></li>
<li class="chapter" data-level="8.5" data-path="dplyr.html"><a href="dplyr.html#case_when"><i class="fa fa-check"></i><b>8.5</b> <code>case_when()</code></a></li>
<li class="chapter" data-level="8.6" data-path="dplyr.html"><a href="dplyr.html#gotchas"><i class="fa fa-check"></i><b>8.6</b> Gotchas</a><ul>
<li class="chapter" data-level="8.6.1" data-path="dplyr.html"><a href="dplyr.html#nested-quoting-functions"><i class="fa fa-check"></i><b>8.6.1</b> Nested quoting functions</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="9" data-path="ggplot2.html"><a href="ggplot2.html"><i class="fa fa-check"></i><b>9</b> ggplot2</a></li>
<li class="part"><span><b>III Going further</b></span></li>
<li class="chapter" data-level="10" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html"><i class="fa fa-check"></i><b>10</b> A rich toolbox</a><ul>
<li class="chapter" data-level="10.1" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html#todo-quote-expr-and-enexpr"><i class="fa fa-check"></i><b>10.1</b> TODO <code>quote()</code>, <code>expr()</code> and <code>enexpr()</code></a></li>
<li class="chapter" data-level="10.2" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html#todo-quo-and-enquo"><i class="fa fa-check"></i><b>10.2</b> TODO <code>quo()</code> and <code>enquo()</code></a></li>
<li class="chapter" data-level="10.3" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html#todo-vars-quos-and-enquos"><i class="fa fa-check"></i><b>10.3</b> TODO <code>vars()</code>, <code>quos()</code> and <code>enquos()</code></a></li>
<li class="chapter" data-level="10.4" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html#toolbox-qq-show"><i class="fa fa-check"></i><b>10.4</b> TODO <code>qq_show()</code></a></li>
<li class="chapter" data-level="10.5" data-path="a-rich-toolbox.html"><a href="a-rich-toolbox.html#todo-sym-and-syms"><i class="fa fa-check"></i><b>10.5</b> TODO <code>sym()</code> and <code>syms()</code></a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="creating-grammars.html"><a href="creating-grammars.html"><i class="fa fa-check"></i><b>11</b> Creating grammars</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">Tidy evaluation</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="dplyr" class="section level1">
<h1><span class="header-section-number">8</span> dplyr</h1>
<p>In the introductory vignette we learned that creating tidy eval functions boils down to a single pattern: quote and unquote. In this vignette we’ll apply this pattern in a series of recipes for dplyr.</p>
<p>This vignette is organised so that you can quickly find your way to a copy-paste solution when you face an immediate problem.</p>
<div id="patterns-for-single-arguments" class="section level2">
<h2><span class="header-section-number">8.1</span> Patterns for single arguments</h2>
<div id="enquo-and---quote-and-unquote-arguments" class="section level3">
<h3><span class="header-section-number">8.1.1</span> <code>enquo()</code> and <code>!!</code> - Quote and unquote arguments</h3>
<p>We start with a quick recap of the introductory vignette. Creating a function around dplyr pipelines involves three steps: abstraction, quoting, and unquoting.</p>
<ul>
<li><p><strong>Abstraction step</strong></p>
<p>First identify the varying parts:</p>
<pre class="sourceCode r"><code class="sourceCode r">df1 <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">group_by</span>(x1) <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(y1))
df2 <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">group_by</span>(x2) <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(y2))
df3 <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">group_by</span>(x3) <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(y3))
df4 <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">group_by</span>(x4) <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(y4))</code></pre>
<p>And abstract those away with a informative argument names:</p>
<pre class="sourceCode r"><code class="sourceCode r">data <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">group_by</span>(group_var) <span class="op">%&gt;%</span><span class="st"> </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(summary_var))</code></pre>
<p>And wrap in a function:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean &lt;-<span class="st"> </span><span class="cf">function</span>(data, group_var, summary_var) {
  data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(group_var) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(summary_var))
}</code></pre></li>
<li><p><strong>Quoting step</strong></p>
<p>Identify all the arguments where the user is allowed to refer to data frame columns directly. The function can’t evaluate these arguments right away. Instead they should be automatically quoted. Apply <code>enquo()</code> to these arguments</p>
<pre class="sourceCode r"><code class="sourceCode r">group_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(group_var)
summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(summary_var)</code></pre></li>
<li><p><strong>Unquoting step</strong></p>
<p>Identify where these variables are passed to other quoting functions and unquote with <code>!!</code>. In this case we pass <code>group_var</code> to <code>group_by()</code> and <code>summary_var</code> to <code>summarise()</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">data <span class="op">%&gt;%</span>
<span class="st">  </span><span class="kw">group_by</span>(<span class="op">!!</span>group_var) <span class="op">%&gt;%</span>
<span class="st">  </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(<span class="op">!!</span>summary_var))</code></pre></li>
</ul>
<p>We end up with a function that automatically quotes its arguments <code>group_var</code> and <code>summary_var</code> and unquotes them when they are passed to other quoting functions:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean &lt;-<span class="st"> </span><span class="cf">function</span>(data, group_var, summary_var) {
  group_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(group_var)
  summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(summary_var)

  data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!</span>group_var) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(<span class="op">!!</span>summary_var))
}

<span class="kw">grouped_mean</span>(mtcars, cyl, mpg)
<span class="co">#&gt; # A tibble: 3 x 2</span>
<span class="co">#&gt;     cyl  mean</span>
<span class="co">#&gt;   &lt;dbl&gt; &lt;dbl&gt;</span>
<span class="co">#&gt; 1     4  26.7</span>
<span class="co">#&gt; 2     6  19.7</span>
<span class="co">#&gt; 3     8  15.1</span></code></pre>
</div>
<div id="quo_name---create-default-column-names" class="section level3">
<h3><span class="header-section-number">8.1.2</span> <code>quo_name()</code> - Create default column names</h3>
<p>Use <code>quo_name()</code> to transform a quoted expression to a column name:</p>
<pre class="sourceCode r"><code class="sourceCode r">simple_var &lt;-<span class="st"> </span><span class="kw">quote</span>(height)
<span class="kw">quo_name</span>(simple_var)
<span class="co">#&gt; [1] &quot;height&quot;</span></code></pre>
<p>These names are only a default stopgap. For more complex uses, you’ll probably want to let the user override the default. Here is a case where the default name is clearly suboptimal:</p>
<pre class="sourceCode r"><code class="sourceCode r">complex_var &lt;-<span class="st"> </span><span class="kw">quote</span>(<span class="kw">mean</span>(height, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>))
<span class="kw">quo_name</span>(complex_var)
<span class="co">#&gt; [1] &quot;mean(height, na.rm = TRUE)&quot;</span></code></pre>
</div>
<div id="and---unquote-column-names" class="section level3">
<h3><span class="header-section-number">8.1.3</span> <code>:=</code> and <code>!!</code> - Unquote column names</h3>
<p>In expressions like <code>c(name = NA)</code>, the argument name is quoted. Because of the quoting it’s not possible to make an indirect reference to a variable that contains a name:</p>
<pre class="sourceCode r"><code class="sourceCode r">name &lt;-<span class="st"> &quot;the real name&quot;</span>
<span class="kw">c</span>(<span class="dt">name =</span> <span class="ot">NA</span>)
<span class="co">#&gt; name </span>
<span class="co">#&gt;   NA</span></code></pre>
<p>In tidy eval function it is possible to unquote argument names with <code>!!</code>. However you need the special <code>:=</code> operator:</p>
<pre class="sourceCode r"><code class="sourceCode r">rlang<span class="op">::</span><span class="kw">qq_show</span>(<span class="kw">c</span>(<span class="op">!!</span>name <span class="op">:</span><span class="er">=</span><span class="st"> </span><span class="ot">NA</span>))
<span class="co">#&gt; c(&quot;the real name&quot; := NA)</span></code></pre>
<p>This unusual operator is needed because using <code>!</code> on the left-hand side of <code>=</code> is not valid R code:</p>
<pre class="sourceCode r"><code class="sourceCode r">rlang<span class="op">::</span><span class="kw">qq_show</span>(<span class="kw">c</span>(<span class="op">!!</span><span class="dt">name =</span> <span class="ot">NA</span>))
<span class="co">#&gt; Error: &lt;text&gt;:1:25: 意外的&#39;=&#39;</span>
<span class="co">#&gt; 1: rlang::qq_show(c(!!name =</span>
<span class="co">#&gt;                             ^</span></code></pre>
<p>Let’s use this <code>!!</code> technique to pass custom column names to <code>group_by()</code> and <code>summarise()</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean &lt;-<span class="st"> </span><span class="cf">function</span>(data, group_var, summary_var) {
  group_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(group_var)
  summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(summary_var)

  <span class="co"># Create default column names</span>
  group_nm &lt;-<span class="st"> </span><span class="kw">quo_name</span>(group_var)
  summary_nm &lt;-<span class="st"> </span><span class="kw">quo_name</span>(summary_var)

  <span class="co"># Prepend with an informative prefix</span>
  group_nm &lt;-<span class="st"> </span><span class="kw">paste0</span>(<span class="st">&quot;group_&quot;</span>, group_nm)
  summary_nm &lt;-<span class="st"> </span><span class="kw">paste0</span>(<span class="st">&quot;mean_&quot;</span>, summary_nm)

  data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!</span>group_nm <span class="op">:</span><span class="er">=</span><span class="st"> </span><span class="op">!!</span>group_var) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="op">!!</span>summary_nm <span class="op">:</span><span class="er">=</span><span class="st"> </span><span class="kw">mean</span>(<span class="op">!!</span>summary_var))
}

<span class="kw">grouped_mean</span>(mtcars, cyl, mpg)
<span class="co">#&gt; # A tibble: 3 x 2</span>
<span class="co">#&gt;   group_cyl mean_mpg</span>
<span class="co">#&gt;       &lt;dbl&gt;    &lt;dbl&gt;</span>
<span class="co">#&gt; 1         4     26.7</span>
<span class="co">#&gt; 2         6     19.7</span>
<span class="co">#&gt; 3         8     15.1</span></code></pre>
</div>
</div>
<div id="patterns-for-multiple-arguments" class="section level2">
<h2><span class="header-section-number">8.2</span> Patterns for multiple arguments</h2>
<div id="forward-multiple-arguments" class="section level3">
<h3><span class="header-section-number">8.2.1</span> <code>...</code> - Forward multiple arguments</h3>
<p>We have created a function that takes one grouping variable and one summary variable. It would make sense to take multiple grouping variables instead of just one. Let’s adjust our function with a <code>...</code> argument.</p>
<ol style="list-style-type: decimal">
<li><p>Replace <code>group_var</code> by <code>...</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="cf">function</span>(data, ..., summary_var)</code></pre></li>
<li><p>Swap <code>...</code> and <code>summary_var</code> because arguments on the right-hand side of <code>...</code> are harder to pass. They can only be passed with their full name explictly specified while arguments on the left-hand side can be passed without name:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="cf">function</span>(data, summary_var, ...)</code></pre></li>
<li><p>It’s good practice to prefix named arguments with a <code>.</code> to reduce the risk of conflicts between your arguments and the arguments passed to <code>...</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="cf">function</span>(.data, .summary_var, ...)</code></pre></li>
</ol>
<p>Because of the magic of dots forwarding we don’t have to use the quote-and-unquote pattern. We can just pass <code>...</code> to other quoting functions like <code>group_by()</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean &lt;-<span class="st"> </span><span class="cf">function</span>(.data, .summary_var, ...) {
  summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(.summary_var)

  .data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(...) <span class="op">%&gt;%</span><span class="st">  </span><span class="co"># Forward `...`</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(<span class="op">!!</span>summary_var))
}

<span class="kw">grouped_mean</span>(mtcars, disp, cyl, am)
<span class="co">#&gt; # A tibble: 6 x 3</span>
<span class="co">#&gt; # Groups:   cyl [3]</span>
<span class="co">#&gt;     cyl    am  mean</span>
<span class="co">#&gt;   &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;</span>
<span class="co">#&gt; 1     4     0 136. </span>
<span class="co">#&gt; 2     4     1  93.6</span>
<span class="co">#&gt; 3     6     0 205. </span>
<span class="co">#&gt; 4     6     1 155  </span>
<span class="co">#&gt; 5     8     0 358. </span>
<span class="co">#&gt; # … with 1 more row</span></code></pre>
<p>Forwarding <code>...</code> is straightforward but has the downside that you can’t modify the arguments or their names.</p>
</div>
<div id="enquos-and---quote-and-unquote-multiple-arguments" class="section level3">
<h3><span class="header-section-number">8.2.2</span> <code>enquos()</code> and <code>!!!</code> - Quote and unquote multiple arguments</h3>
<p>Quoting and unquoting multiple variables with <code>...</code> is pretty much the same process as for single arguments:</p>
<ul>
<li><p>Quoting multiple arguments can be done in two ways: internal quoting with the plural variant <code>enquos()</code> and external quoting with <code>vars()</code>. Use internal quoting when your function takes expressions with <code>...</code> and external quoting when your function takes a list of expressions.</p></li>
<li><p>Unquoting multiple arguments requires a variant of <code>!!</code>, the unquote-splice operator <code>!!!</code> which unquotes each element of a list as an independent argument in the surrounding function call.</p></li>
</ul>
<p>Quote the dots with <code>enquos()</code> and unquote-splice them with <code>!!!</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean2 &lt;-<span class="st"> </span><span class="cf">function</span>(.data, .summary_var, ...) {
  summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(.summary_var)
  group_vars &lt;-<span class="st"> </span><span class="kw">enquos</span>(...)  <span class="co"># Get a list of quoted dots</span>

  .data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!!</span>group_vars) <span class="op">%&gt;%</span><span class="st">  </span><span class="co"># Unquote-splice the list</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(<span class="op">!!</span>summary_var))
}

<span class="kw">grouped_mean2</span>(mtcars, disp, cyl, am)
<span class="co">#&gt; # A tibble: 6 x 3</span>
<span class="co">#&gt; # Groups:   cyl [3]</span>
<span class="co">#&gt;     cyl    am  mean</span>
<span class="co">#&gt;   &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;</span>
<span class="co">#&gt; 1     4     0 136. </span>
<span class="co">#&gt; 2     4     1  93.6</span>
<span class="co">#&gt; 3     6     0 205. </span>
<span class="co">#&gt; 4     6     1 155  </span>
<span class="co">#&gt; 5     8     0 358. </span>
<span class="co">#&gt; # … with 1 more row</span></code></pre>
<p>The quote-and-unquote pattern does more work than simple forwarding of <code>...</code> and is functionally identical. Don’t do this extra work unless you need to modify the arguments or their names.</p>
</div>
<div id="expr---modify-quoted-arguments" class="section level3">
<h3><span class="header-section-number">8.2.3</span> <code>expr()</code> - Modify quoted arguments</h3>
<p>Modifying quoted expressions is often necessary when dealing with multiple arguments. Say we’d like a <code>grouped_mean()</code> variant that takes multiple summary variables rather than multiple grouping variables. We need to somehow take the <code>mean()</code> of each summary variable.</p>
<p>One easy way is to use the quote-and-unquote pattern with <code>expr()</code>. This function is just like <code>quote()</code> from base R. It plainly returns your argument, quoted:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">quote</span>(height)
<span class="co">#&gt; height</span>

<span class="kw">expr</span>(height)
<span class="co">#&gt; height</span>


<span class="kw">quote</span>(<span class="kw">mean</span>(height))
<span class="co">#&gt; mean(height)</span>

<span class="kw">expr</span>(<span class="kw">mean</span>(height))
<span class="co">#&gt; mean(height)</span></code></pre>
<p>But <code>expr()</code> has a twist, it has full unquoting support:</p>
<pre class="sourceCode r"><code class="sourceCode r">vars &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="kw">quote</span>(height), <span class="kw">quote</span>(mass))

<span class="kw">expr</span>(<span class="kw">mean</span>(<span class="op">!!</span>vars[[<span class="dv">1</span>]]))
<span class="co">#&gt; mean(height)</span>

<span class="kw">expr</span>(<span class="kw">group_by</span>(<span class="op">!!!</span>vars))
<span class="co">#&gt; group_by(height, mass)</span></code></pre>
<p>You can loop over a list of arguments and modify each of them:</p>
<pre class="sourceCode r"><code class="sourceCode r">purrr<span class="op">::</span><span class="kw">map</span>(vars, <span class="cf">function</span>(var) <span class="kw">expr</span>(<span class="kw">mean</span>(<span class="op">!!</span>var, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>)))
<span class="co">#&gt; [[1]]</span>
<span class="co">#&gt; mean(height, na.rm = TRUE)</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; [[2]]</span>
<span class="co">#&gt; mean(mass, na.rm = TRUE)</span></code></pre>
<p>This makes it easy to take multiple summary variables, wrap them in a call to <code>mean()</code>, before unquote-splicing within <code>summarise()</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean3 &lt;-<span class="st"> </span><span class="cf">function</span>(.data, .group_var, ...) {
  group_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(.group_var)
  summary_vars &lt;-<span class="st"> </span><span class="kw">enquos</span>(...)  <span class="co"># Get a list of quoted summary variables</span>

  summary_vars &lt;-<span class="st"> </span>purrr<span class="op">::</span><span class="kw">map</span>(summary_vars, <span class="cf">function</span>(var) {
    <span class="kw">expr</span>(<span class="kw">mean</span>(<span class="op">!!</span>var, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>))
  })

  .data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!</span>group_var) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="op">!!!</span>summary_vars)  <span class="co"># Unquote-splice the list</span>
}</code></pre>
</div>
<div id="sec:external-quoting" class="section level3">
<h3><span class="header-section-number">8.2.4</span> <code>vars()</code> - Quote multiple arguments externally</h3>
<p>How could we take multiple summary variables in addition to multiple grouping variables? Internal quoting with <code>...</code> has a major disadvantage: the arguments in <code>...</code> can only have one purpose. If you need to quote multiple sets of variables you have to delegate the quoting to another function. That’s the purpose of <code>vars()</code> which quotes its arguments and returns a list:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">vars</span>(species, gender)
<span class="co">#&gt; &lt;list_of&lt;quosure&gt;&gt;</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; [[1]]</span>
<span class="co">#&gt; &lt;quosure&gt;</span>
<span class="co">#&gt; expr: ^species</span>
<span class="co">#&gt; env:  global</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; [[2]]</span>
<span class="co">#&gt; &lt;quosure&gt;</span>
<span class="co">#&gt; expr: ^gender</span>
<span class="co">#&gt; env:  global</span></code></pre>
<p>The arguments can be complex expressions and have names:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">vars</span>(<span class="dt">h =</span> height, <span class="dt">m =</span> mass <span class="op">/</span><span class="st"> </span><span class="dv">100</span>)
<span class="co">#&gt; &lt;list_of&lt;quosure&gt;&gt;</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; $h</span>
<span class="co">#&gt; &lt;quosure&gt;</span>
<span class="co">#&gt; expr: ^height</span>
<span class="co">#&gt; env:  global</span>
<span class="co">#&gt; </span>
<span class="co">#&gt; $m</span>
<span class="co">#&gt; &lt;quosure&gt;</span>
<span class="co">#&gt; expr: ^mass / 100</span>
<span class="co">#&gt; env:  global</span></code></pre>
<p>When the quoting is external you don’t use <code>enquos()</code>. Simply take lists of expressions in your function and forward the lists to other quoting functions with <code>!!!</code>:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean3 &lt;-<span class="st"> </span><span class="cf">function</span>(data, group_vars, summary_vars) {
  <span class="kw">stopifnot</span>(
    <span class="kw">is.list</span>(group_vars),
    <span class="kw">is.list</span>(summary_vars)
  )

  summary_vars &lt;-<span class="st"> </span>purrr<span class="op">::</span><span class="kw">map</span>(summary_vars, <span class="cf">function</span>(var) {
    <span class="kw">expr</span>(<span class="kw">mean</span>(<span class="op">!!</span>var, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>))
  })

  data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!!</span>group_vars) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">n =</span> <span class="kw">n</span>(), <span class="op">!!!</span>summary_vars)
}

<span class="kw">grouped_mean3</span>(starwars, <span class="kw">vars</span>(species, gender), <span class="kw">vars</span>(height))
<span class="co">#&gt; # A tibble: 43 x 4</span>
<span class="co">#&gt; # Groups:   species [38]</span>
<span class="co">#&gt;   species  gender     n `mean(height, na.rm = TRUE)`</span>
<span class="co">#&gt;   &lt;chr&gt;    &lt;chr&gt;  &lt;int&gt;                        &lt;dbl&gt;</span>
<span class="co">#&gt; 1 &lt;NA&gt;     female     3                          137</span>
<span class="co">#&gt; 2 &lt;NA&gt;     male       2                          183</span>
<span class="co">#&gt; 3 Aleena   male       1                           79</span>
<span class="co">#&gt; 4 Besalisk male       1                          198</span>
<span class="co">#&gt; 5 Cerean   male       1                          198</span>
<span class="co">#&gt; # … with 38 more rows</span>

<span class="kw">grouped_mean3</span>(starwars, <span class="kw">vars</span>(gender), <span class="kw">vars</span>(height, mass))
<span class="co">#&gt; # A tibble: 5 x 4</span>
<span class="co">#&gt;   gender            n `mean(height, na.rm = TRUE… `mean(mass, na.rm = TRUE…</span>
<span class="co">#&gt;   &lt;chr&gt;         &lt;int&gt;                       &lt;dbl&gt;                     &lt;dbl&gt;</span>
<span class="co">#&gt; 1 &lt;NA&gt;              3                        120                       46.3</span>
<span class="co">#&gt; 2 female           19                        165.                      54.0</span>
<span class="co">#&gt; 3 hermaphrodite     1                        175                     1358  </span>
<span class="co">#&gt; 4 male             62                        179.                      81.0</span>
<span class="co">#&gt; 5 none              2                        200                      140</span></code></pre>
<p>One advantage of <code>vars()</code> is that it lets users specify their own names:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">grouped_mean3</span>(starwars, <span class="kw">vars</span>(gender), <span class="kw">vars</span>(<span class="dt">h =</span> height, <span class="dt">m =</span> mass))
<span class="co">#&gt; # A tibble: 5 x 4</span>
<span class="co">#&gt;   gender            n     h      m</span>
<span class="co">#&gt;   &lt;chr&gt;         &lt;int&gt; &lt;dbl&gt;  &lt;dbl&gt;</span>
<span class="co">#&gt; 1 &lt;NA&gt;              3  120    46.3</span>
<span class="co">#&gt; 2 female           19  165.   54.0</span>
<span class="co">#&gt; 3 hermaphrodite     1  175  1358  </span>
<span class="co">#&gt; 4 male             62  179.   81.0</span>
<span class="co">#&gt; 5 none              2  200   140</span></code></pre>
</div>
<div id="enquos.named-true---automatically-add-default-names" class="section level3">
<h3><span class="header-section-number">8.2.5</span> <code>enquos(.named = TRUE)</code> - Automatically add default names</h3>
<p>If you pass <code>.named = TRUE</code> to <code>enquos()</code> the unnamed expressions are automatically given default names:</p>
<pre class="sourceCode r"><code class="sourceCode r">f &lt;-<span class="st"> </span><span class="cf">function</span>(...) <span class="kw">names</span>(<span class="kw">enquos</span>(..., <span class="dt">.named =</span> <span class="ot">TRUE</span>))

<span class="kw">f</span>(height, <span class="kw">mean</span>(mass))
<span class="co">#&gt; [1] &quot;height&quot;     &quot;mean(mass)&quot;</span></code></pre>
<p>User-supplied names are never overridden:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">f</span>(height, <span class="dt">m =</span> <span class="kw">mean</span>(mass))
<span class="co">#&gt; [1] &quot;height&quot; &quot;m&quot;</span></code></pre>
<p>This is handy when you need to modify the names of quoted expressions. In this example we’ll ensure the list is named before adding a prefix:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean2 &lt;-<span class="st"> </span><span class="cf">function</span>(.data, .summary_var, ...) {
  summary_var &lt;-<span class="st"> </span><span class="kw">enquo</span>(.summary_var)
  group_vars &lt;-<span class="st"> </span><span class="kw">enquos</span>(..., <span class="dt">.named =</span> <span class="ot">TRUE</span>)  <span class="co"># Ensure quoted dots are named</span>

  <span class="co"># Prefix the names of the list of quoted dots</span>
  <span class="kw">names</span>(group_vars) &lt;-<span class="st"> </span><span class="kw">paste0</span>(<span class="st">&quot;group_&quot;</span>, <span class="kw">names</span>(group_vars))

  .data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!!</span>group_vars) <span class="op">%&gt;%</span><span class="st">  </span><span class="co"># Unquote-splice the list</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">mean =</span> <span class="kw">mean</span>(<span class="op">!!</span>summary_var))
}

<span class="kw">grouped_mean2</span>(mtcars, disp, cyl, am)
<span class="co">#&gt; # A tibble: 6 x 3</span>
<span class="co">#&gt; # Groups:   group_cyl [3]</span>
<span class="co">#&gt;   group_cyl group_am  mean</span>
<span class="co">#&gt;       &lt;dbl&gt;    &lt;dbl&gt; &lt;dbl&gt;</span>
<span class="co">#&gt; 1         4        0 136. </span>
<span class="co">#&gt; 2         4        1  93.6</span>
<span class="co">#&gt; 3         6        0 205. </span>
<span class="co">#&gt; 4         6        1 155  </span>
<span class="co">#&gt; 5         8        0 358. </span>
<span class="co">#&gt; # … with 1 more row</span></code></pre>
<p>One big downside of this technique is that all arguments get a prefix, including the arguments that were given specific names by the user:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">grouped_mean2</span>(mtcars, disp, <span class="dt">c =</span> cyl, <span class="dt">a =</span> am)
<span class="co">#&gt; # A tibble: 6 x 3</span>
<span class="co">#&gt; # Groups:   group_c [3]</span>
<span class="co">#&gt;   group_c group_a  mean</span>
<span class="co">#&gt;     &lt;dbl&gt;   &lt;dbl&gt; &lt;dbl&gt;</span>
<span class="co">#&gt; 1       4       0 136. </span>
<span class="co">#&gt; 2       4       1  93.6</span>
<span class="co">#&gt; 3       6       0 205. </span>
<span class="co">#&gt; 4       6       1 155  </span>
<span class="co">#&gt; 5       8       0 358. </span>
<span class="co">#&gt; # … with 1 more row</span></code></pre>
<p>In general it’s better to preserve the names explicitly passed by the user. To do that we can’t automatically add default names with <code>enquos()</code> because once the list is fully named we don’t have any way of detecting which arguments were passed with an explicit names. We’ll have to add default names manually with <code>quos_auto_name()</code>.</p>
</div>
<div id="quos_auto_name---manually-add-default-names" class="section level3">
<h3><span class="header-section-number">8.2.6</span> <code>quos_auto_name()</code> - Manually add default names</h3>
<p>It can be helpful add default names to the list of quoted dots manually:</p>
<ul>
<li>We can detect which arguments were explicitly named by the user.</li>
<li>The default names can be applied to lists returned by <code>vars()</code>.</li>
</ul>
<p>Let’s add default names manually with <code>quos_auto_name()</code> to lists of externally quoted variables. We’ll detect unnamed arguments and only add a prefix to this subset of arguments. This way we preserve user-supplied names:</p>
<pre class="sourceCode r"><code class="sourceCode r">grouped_mean3 &lt;-<span class="st"> </span><span class="cf">function</span>(data, group_vars, summary_vars) {
  <span class="kw">stopifnot</span>(
    <span class="kw">is.list</span>(group_vars),
    <span class="kw">is.list</span>(summary_vars)
  )

  <span class="co"># Detect and prefix unnamed arguments:</span>
  unnamed &lt;-<span class="st"> </span><span class="kw">names</span>(summary_vars) <span class="op">==</span><span class="st"> &quot;&quot;</span>

  <span class="co"># Add the default names:</span>
  summary_vars &lt;-<span class="st"> </span>rlang<span class="op">::</span><span class="kw">quos_auto_name</span>(summary_vars)

  prefixed_nms &lt;-<span class="st"> </span><span class="kw">paste0</span>(<span class="st">&quot;mean_&quot;</span>, <span class="kw">names</span>(summary_vars)[unnamed])
  <span class="kw">names</span>(summary_vars)[unnamed] &lt;-<span class="st"> </span>prefixed_nms

  <span class="co"># Expand the argument _after_ giving the list its default names</span>
  summary_vars &lt;-<span class="st"> </span>purrr<span class="op">::</span><span class="kw">map</span>(summary_vars, <span class="cf">function</span>(var) {
    <span class="kw">expr</span>(<span class="kw">mean</span>(<span class="op">!!</span>var, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>))
  })

  data <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">group_by</span>(<span class="op">!!!</span>group_vars) <span class="op">%&gt;%</span>
<span class="st">    </span><span class="kw">summarise</span>(<span class="dt">n =</span> <span class="kw">n</span>(), <span class="op">!!!</span>summary_vars)  <span class="co"># Unquote-splice the renamed list</span>
}</code></pre>
<p>Note how we add the default names <em>before</em> wrapping the arguments in a <code>mean()</code> call. This way we avoid including <code>mean()</code> in the name:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">quo_name</span>(<span class="kw">quote</span>(mass))
<span class="co">#&gt; [1] &quot;mass&quot;</span>

<span class="kw">quo_name</span>(<span class="kw">quote</span>(<span class="kw">mean</span>(mass, <span class="dt">na.rm =</span> <span class="ot">TRUE</span>)))
<span class="co">#&gt; [1] &quot;mean(mass, na.rm = TRUE)&quot;</span></code></pre>
<p>We get nicely prefixed default names:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">grouped_mean3</span>(starwars, <span class="kw">vars</span>(gender), <span class="kw">vars</span>(height, mass))
<span class="co">#&gt; # A tibble: 5 x 4</span>
<span class="co">#&gt;   gender            n mean_height mean_mass</span>
<span class="co">#&gt;   &lt;chr&gt;         &lt;int&gt;       &lt;dbl&gt;     &lt;dbl&gt;</span>
<span class="co">#&gt; 1 &lt;NA&gt;              3        120       46.3</span>
<span class="co">#&gt; 2 female           19        165.      54.0</span>
<span class="co">#&gt; 3 hermaphrodite     1        175     1358  </span>
<span class="co">#&gt; 4 male             62        179.      81.0</span>
<span class="co">#&gt; 5 none              2        200      140</span></code></pre>
<p>And the user is able to fully override the names:</p>
<pre class="sourceCode r"><code class="sourceCode r"><span class="kw">grouped_mean3</span>(starwars, <span class="kw">vars</span>(gender), <span class="kw">vars</span>(<span class="dt">h =</span> height, <span class="dt">m =</span> mass))
<span class="co">#&gt; # A tibble: 5 x 4</span>
<span class="co">#&gt;   gender            n     h      m</span>
<span class="co">#&gt;   &lt;chr&gt;         &lt;int&gt; &lt;dbl&gt;  &lt;dbl&gt;</span>
<span class="co">#&gt; 1 &lt;NA&gt;              3  120    46.3</span>
<span class="co">#&gt; 2 female           19  165.   54.0</span>
<span class="co">#&gt; 3 hermaphrodite     1  175  1358  </span>
<span class="co">#&gt; 4 male             62  179.   81.0</span>
<span class="co">#&gt; 5 none              2  200   140</span></code></pre>
</div>
</div>
<div id="select" class="section level2">
<h2><span class="header-section-number">8.3</span> <code>select()</code></h2>
<p>TODO</p>
</div>
<div id="filter" class="section level2">
<h2><span class="header-section-number">8.4</span> <code>filter()</code></h2>
<p>TODO</p>
</div>
<div id="case_when" class="section level2">
<h2><span class="header-section-number">8.5</span> <code>case_when()</code></h2>
<p>TODO</p>
</div>
<div id="gotchas" class="section level2">
<h2><span class="header-section-number">8.6</span> Gotchas</h2>
<div id="nested-quoting-functions" class="section level3">
<h3><span class="header-section-number">8.6.1</span> Nested quoting functions</h3>
<p><a href="https://stackoverflow.com/questions/51902438/rlangsym-in-anonymous-functions" class="uri">https://stackoverflow.com/questions/51902438/rlangsym-in-anonymous-functions</a></p>

</div>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="glossary.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="ggplot2.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"google": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": ["facebook", "google", "twitter", "linkedin", "weibo", "instapaper"]
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/ShixiangWang/tidyeval/edit/master/dplyr.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"download": null,
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
